# -*- coding: utf-8 -*-
# keywords_heat.py
# Created by Hardy on 24th, Feb
# Copyright 2017 杭州网川教育科技有限公司. All rights reserved.

from querier.esquerier import ElasticSearchQuerier


class WechatKeywordHeatQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type):
        super(WechatKeywordHeatQuerier, self).__init__(es, index, doc_type)
        # self.nlp_service = nlp_service

    def _build_query(self, args):
        filters = args.get('filters', {})
        if filters is None:
            filters = {}
        keywords = filters.get('keywords', [])
        if not keywords:
            raise ValueError('message: "keywords" must be specified in filters')
        query = self._gen_query(filters)
        return query, {}, {'keywords': keywords}

    def _build_result(self, es_result, param):
        # total = es_result['hits']['total']
        agg = es_result['aggregations']
        data = extract_result(agg)
        return {
            'doc_counts': data['doc_counts'],
            'sum_reads': data['sum_reads'],
            'sum_likes': data['sum_likes'],
            'dates': data['dates']
        }

    def _gen_query(self, filters):
        filter_clause = []

        if filters:
            filter_clause = self._add_filter_range_clause(filter_clause, filters, 'publish_timestamp')
            filter_clause = self._add_filter_clause(filter_clause, filters, 'keywords')

        query = {
            "query": {
                "bool": {
                    "filter": filter_clause
                }
            },
            "aggs": {
                "time_hist": {
                    "date_histogram": {
                        "field": "publish_timestamp",
                        # "interval": "1d"
                        "interval": "1w"
                    },
                    "aggs": {
                        "sum_read_num": {"sum": {"field": "read_num", "missing": 0}},
                        "sum_like_num": {"sum": {"field": "like_num", "missing": 0}},
                    }
                }
            },
            "size": 0
        }

        return query

    @staticmethod
    def _add_filter_match(must_clause, filters, key):
        if key in filters:
            if filters[key]:
                clause = []
                must_clause.append({
                    'bool': {'should': clause}
                })
                values = filters[key]
                if isinstance(values, str):
                    values = values.split(' ')
                for fk in values:
                    clause.append({'match': {key: {'query': fk, 'minimum_should_match': '10<85% 20<10'}}})
        return must_clause

    @staticmethod
    def _add_filter_clause(filter_clause, filters, key, cond='must'):
        if key in filters:
            if filters[key]:
                clause = []
                filter_clause.append({
                    'bool': {
                        cond: clause
                    }
                })
                for fk in filters[key]:
                    clause.append({'term': {key: fk}})
        return filter_clause

    @staticmethod
    def _add_filter_range_clause(filter_clause, filters, key):
        if key in filters:
            if filters[key]:
                clause = []
                filter_clause.append({
                    'bool': {
                        'must': clause
                    }
                })
                fk = filters[key]
                if not isinstance(fk, list) or len(fk) < 1:
                    pass
                else:
                    min_fk = fk[0]
                    if len(fk) >= 2:
                        max_fk = fk[1]
                    else:
                        max_fk = None
                    if min_fk is not None and min_fk != 'null':
                        clause.append({'range': {key: {"gte": min_fk}}})
                    if max_fk is not None and max_fk != 'null':
                        clause.append({'range': {key: {"lte": max_fk}}})
        return filter_clause


class WechatMultiKeywordHeatQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type):
        super(WechatMultiKeywordHeatQuerier, self).__init__(es, index, doc_type)
        self.analyzeQuerier = WechatKeywordHeatQuerier(es, index, doc_type)

    def search(self, args):
        filters = args.get('filters', {})
        if filters is None:
            filters = {}
        keywords = filters.get('keywords', [])
        if not keywords:
            raise ValueError('message: "keywords" must be specified in filters')

        publish_timestamp = filters.get('publish_timestamp', [])

        if not publish_timestamp:
            raise ValueError('message: "publish_timestamp" must be specified in filters')

        heat = []
        for value in keywords:
            a = {'filters': {"keywords": [value], "publish_timestamp": publish_timestamp}}
            out = self.analyzeQuerier.search(a)
            out['keyword'] = value
            heat.append(out)

        return {"heat": heat}

    def _build_query(self, args): pass

    def _build_result(self, es_result, param): pass


def extract_result(agg):
    buckets = agg['time_hist']['buckets']
    doc_counts = []
    sum_reads = []
    sum_likes = []
    dates = []

    for b in buckets:
        doc_counts.append(b['doc_count'])
        sum_reads.append(b['sum_read_num']['value'])
        sum_likes.append(b['sum_like_num']['value'])
        dates.append(b['key_as_string'])

    return {
        'doc_counts': doc_counts,
        'sum_reads': sum_reads,
        'sum_likes': sum_likes,
        'dates': dates
    }
